namespace SimpleWebServices.Web.UI.Html
{
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Xml;
    using System.Xml.Serialization;
    using System.Xml.XPath;
    using SimpleWebServices;
    using SimpleWebServices.Web.UI.Html.Elements;
    using Xunit;

    public sealed class MetaCollectionFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<MetaCollection>()
                .DerivesFrom<object>()
                .IsConcreteClass()
                .IsSealed()
                .HasDefaultConstructor()
                .Implements<IEnumerable<Meta>>()
                .Implements<IXmlSerializable>()
                .XmlRoot("metadata")
                .Result);
        }

        [Fact]
        public void deserialize()
        {
            string xml =
                "<metadata>" +
                    "<meta name='DC.date' content='1999-12-31' scheme='W3CDTF' />" +
                    "<foo />" +
                "</metadata>";

            MetaCollection obj = xml.Deserialize<MetaCollection>();

            Assert.True(obj.Contains("DC.date"));
        }

        [Fact]
        public void deserializeEmpty()
        {
            Assert.NotNull("<metadata />".Deserialize<MetaCollection>());
        }

        [Fact]
        public void serialize()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            XPathNavigator navigator = obj.Serialize().CreateNavigator();

            Assert.True((bool)navigator.Evaluate("1=count(/metadata/meta[@name='DC.date'][@content='1999-12-31'][@scheme='W3CDTF'])"));
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new MetaCollection());
        }

        [Fact]
        public void prop_Count()
        {
            Assert.True(new PropertyExpectations(typeof(MetaCollection).GetProperty("Count"))
                .TypeIs<int>()
                .DefaultValueIs(0)
                .Result);
        }

        [Fact]
        public void prop_Count_get()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.Equal<int>(1, obj.Count);
        }

        [Fact]
        public void indexer_stringHttpEquiv_get()
        {
            Meta expected = new Meta
            {
                HttpEquivalent = "content-location",
                Content = "http://example.com/page"
            };

            MetaCollection obj = new MetaCollection
            {
                expected
            };

            Assert.Same(expected, obj["content-location"]);
        }

        [Fact]
        public void indexer_stringName_get()
        {
            Meta expected = new Meta
            {
                Name = "author",
                Content = "John Doe"
            };

            MetaCollection obj = new MetaCollection
            {
                expected
            };

            Assert.Same(expected, obj["author"]);
        }

        [Fact]
        public void indexer_stringMissing_get()
        {
            Assert.Throws<KeyNotFoundException>(() => new MetaCollection()["missing"]);
        }

        [Fact]
        public void opEquality_MetaCollection_MetaCollection()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.True(obj == comparand);
        }

        [Fact]
        public void opEquality_MetaCollection_MetaCollectionDiffers()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection
            {
                new Meta { HttpEquivalent = "content-location", Content = "http://example.com/page" }
            };

            Assert.False(obj == comparand);
        }

        [Fact]
        public void opEquality_MetaCollection_MetaCollectionSame()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = obj;

            Assert.True(obj == comparand);
        }

        [Fact]
        public void opEquality_MetaCollectionNull_MetaCollection()
        {
            MetaCollection obj = null;

            MetaCollection comparand = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.False(obj == comparand);
        }

        [Fact]
        public void opEquality_MetaCollection_MetaCollectionNull()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = null;

            Assert.False(obj == comparand);
        }

        [Fact]
        public void opInequality_MetaCollection_MetaCollection()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.False(obj != comparand);
        }

        [Fact]
        public void opInequality_MetaCollection_MetaCollectionDiffers()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection
            {
                new Meta { HttpEquivalent = "content-location", Content = "http://example.com/page" }
            };

            Assert.True(obj != comparand);
        }

        [Fact]
        public void opInequality_MetaCollection_MetaCollectionSame()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = obj;

            Assert.False(obj != comparand);
        }

        [Fact]
        public void opInequality_MetaCollectionNull_MetaCollection()
        {
            MetaCollection obj = null;

            MetaCollection comparand = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.True(obj != comparand);
        }

        [Fact]
        public void opInequality_MetaCollection_MetaCollectionNull()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = null;

            Assert.True(obj != comparand);
        }

        [Fact]
        public void op_Add_MetaCollection()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection();
            comparand.Add(obj);

            Assert.True(obj == comparand);
        }

        [Fact]
        public void op_Add_MetaCollectionNull()
        {
            Assert.Throws<ArgumentNullException>(() => new MetaCollection().Add(null as MetaCollection));
        }

        [Fact]
        public void op_Add_Meta()
        {
            Meta meta = new Meta
            {
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            MetaCollection obj = new MetaCollection
            {
                meta
            };

            MetaCollection comparand = new MetaCollection();
            comparand.Add(meta);

            Assert.True(obj == comparand);
        }

        [Fact]
        public void op_Add_MetaNull()
        {
            Assert.Throws<ArgumentNullException>(() => new MetaCollection().Add(null as Meta));
        }

        [Fact]
        public void op_Contains_stringHttpEquiv()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta
                {
                    HttpEquivalent = "content-location",
                    Content = "http://example.com/page"
                }
            };

            Assert.True(obj.Contains("content-location"));
        }

        [Fact]
        public void op_Contains_stringName()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.True(obj.Contains("DC.date"));
        }

        [Fact]
        public void op_Contains_stringFalse()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.False(obj.Contains("DC.description"));
        }

        [Fact]
        public void op_Contains_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new MetaCollection().Contains(null as string));
        }

        [Fact]
        public void op_Contains_stringEmpty()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new MetaCollection().Contains(string.Empty));
        }

        [Fact]
        public void op_Contains_MetaTrue()
        {
            Meta meta = new Meta
            {
                Name = "DC.date",
                Content = "1999-12-31",
                Scheme = "W3CDTF"
            };

            MetaCollection obj = new MetaCollection
            {
                meta
            };

            Assert.True(obj.Contains(meta));
        }

        [Fact]
        public void op_Contains_MetaFalse()
        {
            Meta meta = new Meta
            {
                HttpEquivalent = "content-location",
                Content = "http://example.com/page"
            };

            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.False(obj.Contains(meta));
        }

        [Fact]
        public void op_Contains_MetaNull()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta
                {
                    HttpEquivalent = "content-location",
                    Content = "http://example.com/page"
                }
            };

            Assert.False(obj.Contains(null as Meta));
        }

        [Fact]
        public void op_Equals_object()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.True(obj.Equals(comparand as object));
        }

        [Fact]
        public void op_Equals_objectDiffer()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            MetaCollection comparand = new MetaCollection
            {
                new Meta { HttpEquivalent = "content-location", Content = "http://example.com/page" }
            };

            Assert.False(obj.Equals(comparand as object));
        }

        [Fact]
        public void op_Equals_objectSame()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            Assert.True(obj.Equals(obj as object));
        }

        [Fact]
        public void op_Equals_objectNull()
        {
            Assert.False(new MetaCollection().Equals(null as object));
        }

        [Fact]
        public void op_Equals_objectString()
        {
            Assert.False(new MetaCollection().Equals(string.Empty as object));
        }

        [Fact]
        public void op_GetHashCode()
        {
            MetaCollection obj = new MetaCollection
            {
                new Meta { Name = "DC.date", Content = "1999-12-31", Scheme = "W3CDTF" }
            };

            int expected = obj.ToString().GetHashCode();
            int actual = obj.GetHashCode();

            Assert.Equal<int>(expected, actual);
        }

        [Fact]
        public void IEnumerable_op_GetEnumerator()
        {
            Assert.NotNull((new MetaCollection() as IEnumerable).GetEnumerator());
        }

        [Fact]
        public void IEnumerableOfT_op_GetEnumerator()
        {
            Assert.NotNull((new MetaCollection() as IEnumerable<Meta>).GetEnumerator());
        }

        [Fact]
        public void IXmlSerializable_op_GetSchema()
        {
            Assert.Throws<NotSupportedException>(() => (new MetaCollection() as IXmlSerializable).GetSchema());
        }

        [Fact]
        public void IXmlSerializable_op_ReadXml_XmlReaderNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new MetaCollection() as IXmlSerializable).ReadXml(null as XmlReader));
        }

        [Fact]
        public void IXmlSerializable_op_WriteXml_XmlWriterNull()
        {
            Assert.Throws<ArgumentNullException>(() => (new MetaCollection() as IXmlSerializable).WriteXml(null as XmlWriter));
        }
    }
}